#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
+#include "version.h"
#include "privcmd.h"
#include "xen.h"
free (handle);
}
-/* Make Xen hypervisor call */
-int xi_make_dom0_op(xi_handle *handle, dom0_op_t *op, int opcode)
+/* Make simple xen version hypervisor calls */
+static int xi_make_xen_version_hypercall(xi_handle *handle, long *vnum, xen_extraversion_t *ver)
+{
+ privcmd_hypercall_t privcmd;
+ multicall_entry_t multicall[2];
+ int ret = 0;
+
+ /* set up for doing hypercall */
+ privcmd.op = __HYPERVISOR_multicall;
+ privcmd.arg[0] = (unsigned long)multicall;
+ privcmd.arg[1] = 2;
+
+ /* first one to get xen version number */
+ multicall[0].op = __HYPERVISOR_xen_version;
+ multicall[0].args[0] = (unsigned long)XENVER_version;
+
+ /* second to get xen version flag */
+ multicall[1].op = __HYPERVISOR_xen_version;
+ multicall[1].args[0] = (unsigned long)XENVER_extraversion;
+ multicall[1].args[1] = (unsigned long)ver;
+
+ if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
+ perror("Failed to mlock privcmd structure");
+ return -1;
+ }
+
+ if (mlock( multicall, sizeof(multicall_entry_t)) < 0) {
+ perror("Failed to mlock multicall_entry structure");
+ munlock( &multicall, sizeof(multicall_entry_t));
+ return -1;
+ }
+
+ if (ioctl( handle->fd, IOCTL_PRIVCMD_HYPERCALL, &privcmd) < 0) {
+ perror("Hypercall failed");
+ ret = -1;
+ }
+
+ *vnum = multicall[0].result;
+
+ munlock( &privcmd, sizeof(privcmd_hypercall_t));
+ munlock( &multicall, sizeof(multicall_entry_t));
+
+ return ret;
+}
+
+/* Make Xen Dom0 op hypervisor call */
+static int xi_make_dom0_op(xi_handle *handle, dom0_op_t *dom_op, int dom_opcode)
{
privcmd_hypercall_t privcmd;
int ret = 0;
/* set up for doing hypercall */
privcmd.op = __HYPERVISOR_dom0_op;
- privcmd.arg[0] = (unsigned long)op;
- op->cmd = opcode;
- op->interface_version = DOM0_INTERFACE_VERSION;
+ privcmd.arg[0] = (unsigned long)dom_op;
+ dom_op->cmd = dom_opcode;
+ dom_op->interface_version = DOM0_INTERFACE_VERSION;
if (mlock( &privcmd, sizeof(privcmd_hypercall_t)) < 0) {
perror("Failed to mlock privcmd structure");
return -1;
}
- if (mlock( op, sizeof(dom0_op_t)) < 0) {
+ if (mlock( dom_op, sizeof(dom0_op_t)) < 0) {
perror("Failed to mlock dom0_op structure");
munlock( &privcmd, sizeof(privcmd_hypercall_t));
return -1;
}
munlock( &privcmd, sizeof(privcmd_hypercall_t));
- munlock( op, sizeof(dom0_op_t));
+ munlock( dom_op, sizeof(dom0_op_t));
return ret;
}
return op.u.getvcpucontext.cpu_time;
}
+
+/* gets xen version information from hypervisor */
+int xi_get_xen_version(xi_handle *handle, long *vnum, xen_extraversion_t *ver)
+{
+
+ /* gets the XENVER_version and XENVER_extraversion */
+ if (xi_make_xen_version_hypercall( handle, vnum, ver) < 0) {;
+ perror("XEN VERSION Hypercall failed");
+ return -1;
+ }
+
+ return 0;
+}
#include <unistd.h>
#include <xen-interface.h>
#include "xenstat.h"
+#include "version.h"
/*
* Types
FILE *procnetdev;
};
+#define SHORT_ASC_LEN 5 /* length of 65535 */
+#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
+
struct xenstat_node {
unsigned int flags;
unsigned long long cpu_hz;
unsigned long long tot_mem;
unsigned long long free_mem;
unsigned int num_domains;
+ char xen_version[VERSION_SIZE]; /* xen version running on this node */
xenstat_domain *domains; /* Array of length num_domains */
};
unsigned int state;
unsigned long long cpu_ns;
unsigned int num_vcpus;
- xenstat_vcpu *vcpus; /* Array of length num_vcpus */
+ xenstat_vcpu *vcpus; /* Array of length num_vcpus */
unsigned long long cur_mem; /* Current memory reservation */
unsigned long long max_mem; /* Total memory allowed */
unsigned int ssid;
#define DOMAIN_CHUNK_SIZE 256
xenstat_node *node;
dom0_physinfo_t physinfo;
+ xen_extraversion_t version;
+ long vnum = 0;
dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE];
unsigned int num_domains, new_domains;
unsigned int i;
return NULL;
}
+ /* Get the xen version number and xen version tag */
+ if (xi_get_xen_version(handle->xihandle, &vnum, &version) < 0) {
+ free(node);
+ return NULL;
+ }
+ snprintf(node->xen_version, VERSION_SIZE,
+ "%ld.%ld%s\n", ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, (char *)version);
+
node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL;
node->num_cpus =
(physinfo.threads_per_core * physinfo.cores_per_socket *
if(collectors[i].collect(handle, node) == 0) {
xenstat_free_node(node);
return NULL;
- }
- }
+ }
+ }
}
return node;
return NULL;
}
+const char *xenstat_node_xen_ver(xenstat_node * node)
+{
+ return node->xen_version;
+}
+
unsigned long long xenstat_node_tot_mem(xenstat_node * node)
{
return node->tot_mem;